package com.fingard.dsp.bank.directbank.icbc11;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.bankInterface.IAuthorizeForRec;
import com.fingard.dsp.bank.directbank.icbc11.util.FileEncryptionTest;
import com.fingard.dsp.bank.reqrespobj.authforrec.*;
import com.fingard.dsp.bank.reqrespobj.authforrec.detail.ReqAuthForRecDetail;
import com.fingard.dsp.bank.reqrespobj.authforrec.detail.RetAtsQryAuthForRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;

import java.io.BufferedReader;
import java.io.File;
import java.io.StringReader;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;


public class ICBC11AuthorizeForRec extends ICBC11Base implements IAuthorizeForRec {
	/**
	 * 中国工商银行代理保险客户保费代扣协议文件接口标准
	 * 
	 * 需求描述: 1、通讯方式:FTP或者SFTP 2、交互内容:*.txt文件 3、交互字符集：GBK
	 * 
	 * 渠道说明: 本接口适用于采用批量导入代扣协议的场景，
	 * 控制文件大小，一个文件需控制在2万行的明细记录之内，如果业务数据超过2万，建议按照2万一个文件进行分拆上送
	 * 
	 * @author Colin
	 * @date 2019年12月05日
	 */
	@Override
	/**
	 * 2.2.3保费代扣协议存量导入文件
	 * 
	 * <p>功能描述:</p>
	 * <ul>
	 * 	<li>1、文件名命名规则:</li>
	 * 		<li>ENYASPS+保险公司代码+银行代码+CLPRTL01_日期_3位序列号.txt</li>
	 *  <li>2、文件内容格式说明:</li>
	 *  <li>2)、明细记录：</li>
	 *  	<li>工行地区号|工行网点号|保险公司代码|银行交易渠道|客户姓名|客户证件类型|客户证件号码|客户手机号码|客户银行卡号账号|保险公司协议种类|投保单号/保单号|出单渠道|单笔扣款限额|扣款频度|协议开始日期|协议到期日期|协议备注\n</li>
	 * </ul>
	 * 
	 * @param p_req 签约请求对象
	 * @return 签约响应对象
	 * @throws Exception
	 */
	public RetAtsAuthForRec d_auth(ReqAuthForRec p_req) throws Exception {

		RetAtsAuthForRec retAts = new RetAtsAuthForRec(p_req.reqHeader);
		retAts.reqSeqID = p_req.reqSeqID;

		Date BeginDate = new Date();
		String PrtlBeginDate = Format.Date8Format.format(BeginDate);

		ActSetItem actItem = this.getBankConfig().getActSetItem(p_req.ownAct, "bat");

		if (actItem == null) {
			retAts.respCode = "-1";
			retAts.reqSeqID = p_req.reqSeqID;
			retAts.respInfo = "未找到账号:[" + p_req.ownAct + "]商户配置信息!";
			retAts.retCode = "1";
			retAts.retMsg = "未找到账号:[" + p_req.ownAct + "]商户配置信息!";
			retAts.writeRetToATS();
			return retAts;
		}

		String ZoneNo = actItem.areaCode;
		String BrNo = actItem.cnapsCode;
		String InsuId = bankFront.corpNo;
		String ChanNo = "15";
		String InsuPrtlType = "2";
		String SignChan = "2";
		String LmtAmt = getBankConfig().getMapValueByKey("contractKeyMapping", "singleLimit");
		if (StringHelper.isNullOrEmpty(LmtAmt)) {
			retAts.respCode = "-1";
			retAts.respInfo = "缺失配置节点'singleLimit'或值为空!";
			return retAts;
		}
		LmtAmt = StringHelper.amountMultiply100(LmtAmt);
		String CustPayFreq = "4";

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		// 签约文件内容
		StringBuilder sbFileContent = new StringBuilder();

		// 文件明细
		while (p_req.readRecord()) {
			ReqAuthForRecDetail tmpDetail = p_req.readedDetail;

			String CustName = tmpDetail.oppActName;
			String CustIdType = getBankConfig().getMapValueByKey("certTypeMapping", tmpDetail.certType);
			
			String CustIdNo = tmpDetail.certNum;
			String CustMobile = tmpDetail.cellPhone;
			String CustAccno = tmpDetail.oppAct;
			String insuPrtlNo = tmpDetail.sourceNoteCode;
			String PrtlEndDate = Format.Date8Format.format(sdf.parse(tmpDetail.deadLine));
			String PrtlNote = tmpDetail.authCode;

			// 工行地区号|工行网点号|保险公司代码|银行交易渠道|客户姓名|客户证件类型|客户证件号码|客户手机号码|客户银行卡号账号|保险公司协议种类|投保单号/保单号|出单渠道|单笔扣款限额|扣款频度|协议开始日期|协议到期日期|协议备注\n
			String tmpReqBodyDetail = MessageFormat.format("{0}^{1}^{2}^{3}^{4}^{5}^{6}^{7}^{8}^{9}^{10}^{11}^{12}^{13}^{14}^{15}^{16}\n", ZoneNo, BrNo, InsuId,
					ChanNo, CustName, CustIdType, CustIdNo, CustMobile, CustAccno, InsuPrtlType, insuPrtlNo, SignChan, LmtAmt, CustPayFreq, PrtlBeginDate,
					PrtlEndDate, PrtlNote);
			sbFileContent.append(tmpReqBodyDetail);

		}

		WriteBankLogLn2("批次文件内容:\r\n" + sbFileContent.toString());

		String tmpMarkDataDir = getDataFileDirectory(BeginDate) + File.separator + "auth";

		int maxBatch = 0;
		File dataFileDir = new File(tmpMarkDataDir);
		if (dataFileDir.exists()) {
			int len = dataFileDir.listFiles().length;
			if (len > 0) {
				maxBatch = len + 1;
			} else {
				maxBatch = 1;
			}
		} else {
			maxBatch = 1;
		}

		// ENYASPS+保险公司代码+银行代码+CLPRTL01_日期_3位序列号.txt
		String tmpUpFilePrefix = "ENYASPS" + bankFront.corpNo + "ICBC" + "CLPRTL01_" + PrtlBeginDate + "_" + String.format("%3s", maxBatch).replace(" ", "0");
		String tmpUploadFileName = tmpUpFilePrefix + ".txt";
		// 保存映射文件
		String tmpLocalMarkPath = StringHelper.trimEnd(tmpMarkDataDir, File.separator) + File.separator + p_req.reqSeqID + ".txt";
		WriteBankLogLn2("批次号映射文件路径: " + tmpLocalMarkPath);
		FileHelper.writeFile(tmpLocalMarkPath, tmpUploadFileName, getCharset());

		// 保存待发送文件
		String tmpLocalPath = getTempFileDirectory() + File.separator + tmpUploadFileName;
		WriteBankLogLn2("批次文件保存本机路径: " + tmpLocalPath);
		FileHelper.writeFile(tmpLocalPath, sbFileContent.toString(), getCharset());

		// 是否加密文件
		if (getBankConfig().getValueAsBool("IsEncryption")) {
			String EncryptKey = getBankConfig().getValueAsString("EncryptKey");
			tmpUploadFileName = tmpUploadFileName + ".des";
			tmpLocalPath = FileEncryptionTest.enyFile(tmpLocalPath, EncryptKey);
		}
		// 上送银保通服务器
		FtpSet ftpSet = bankFront.getFtpSet("bat");

		FtpReceiver ftpReceiver = null;
		String requestType = getBankConfig().getValueAsString("requestType");
		if (requestType != null && "SFTP".equals(requestType)) {
			SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
			String sftpFilePath = StringHelper.trimEnd(ftpSet.upDir, "/") + "/" + tmpUploadFileName;
			ftpReceiver = sftpPortClient.uploadFile("", tmpLocalPath, sftpFilePath);
			sftpPortClient.disconnect();
		} else {
			FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
			ftpReceiver = ftpPortClient.uploadFile(tmpLocalPath, tmpUploadFileName);
			ftpPortClient.disconnect();
		}

		retAts.respCode = "0";
		retAts.reqSeqID = p_req.reqSeqID;
		if (!ftpReceiver.isCompleted) {
			retAts.respCode = "-1";
			retAts.reqSeqID = p_req.reqSeqID;
			retAts.respInfo = "文件上传失败，原因:" + ftpReceiver.connMsg;
			retAts.retCode = "1";
			retAts.retMsg = ftpReceiver.connMsg;
		} else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
			retAts.respCode = "-1";
			retAts.reqSeqID = p_req.reqSeqID;
			retAts.respInfo = "文件上传失败，原因:" + ftpReceiver.connMsg;
			retAts.retCode = "1";
			retAts.retMsg = ftpReceiver.connMsg;
		} else {
			retAts.respCode = "0";
			retAts.reqSeqID = p_req.reqSeqID;
			retAts.respInfo = "文件已生成，并已上送银保通服务器";
			retAts.retCode = "2";
		}

		retAts.writeRetToATS();
		return retAts;

	}

	@Override
	/**
	 * 2.2.4保费代扣协议存量导入回盘文件
	 * 
	 * <p>功能描述:</p>
	 * <ul>
	 * 	<li>1、文件名命名规则:</li>
	 * 		<li>ENY+保险公司代码+银行代码+PRTLREP01_日期_3位序列号.txt</li>
	 *  <li>2、文件内容格式说明:</li>
	 *  <li>2)、明细记录：</li>
	 *  	<li>工行地区号|工行网点号|保险公司代码|银行交易渠道|客户姓名|客户证件类型|客户证件号码|客户手机号码|客户银行卡号账号|保险公司协议种类|投保单号/保单号|出单渠道|单笔扣款限额|扣款频度|协议开始日期|协议到期日期|协议备注|处理结果|协议编号|协议状态\n</li>
	 * </ul>
	 * 
	 * @param p_req 签约请求对象
	 * @return 签约响应对象
	 * @throws Exception
	 */
	public RetAtsQryAuthForRec d_qry_auth(ReqQryAuthForRec p_req) throws Exception {

		RetAtsQryAuthForRec retAts = new RetAtsQryAuthForRec(p_req.reqHeader);
		retAts.writeStart();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

		// 取映射文件
		String tmpMarkDataDir = getDataFileDirectory((p_req.startDate.isEmpty()?new Date():sdf.parse(p_req.startDate))) + File.separator + "auth";
		String tmpLocalMarkPath = StringHelper.trimEnd(tmpMarkDataDir, File.separator) + File.separator + p_req.reqSeqID + ".txt";
		String tmpDownFileName = FileHelper.readFileText(tmpLocalMarkPath, getCharset());
		// 回盘文件名命名规则:ENY+保险公司代码+银行代码+PRTLREP01_日期_3位序列号.txt
		if (getBankConfig().getValueAsBool("IsEncryption")) {
			tmpDownFileName = (tmpDownFileName.replace("CLPRTL01", "PRTLREP01")).replace("ENYASPS", "ENY") + ".des";
		} else {
			tmpDownFileName = (tmpDownFileName.replace("CLPRTL01", "PRTLREP01")).replace("ENYASPS", "ENY");
		}
		String tmpLocalPath = createTempFileDirectory() + File.separator + tmpDownFileName;

		WriteBankLogLn2("回盘文件路径:\r\n" + tmpLocalPath);

		FtpSet ftpSet = bankFront.getFtpSet("bat");
		FtpReceiver ftpReceiver = null;
		String requestType = getBankConfig().getValueAsString("requestType");
		if (requestType != null && "SFTP".equals(requestType)) {
			String sftpFilePath = StringHelper.trimEnd(ftpSet.downDir, "/") + "/" + tmpDownFileName;
			WriteBankLogLn2("待下载SFTP服务器文件路径:\r\n" + sftpFilePath);
			SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
			ftpReceiver = sftpPortClient.downloadFile("", sftpFilePath, tmpLocalPath);
			sftpPortClient.disconnect();
			WriteBankLogLn2("下载结束:\r\n" + sftpFilePath);
		} else {
			FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
			ftpReceiver = ftpPortClient.downloadFile(tmpDownFileName, tmpLocalPath);
			ftpPortClient.disconnect();
		}

		WriteBankLogLn2("下载结果:\r\n" + ftpReceiver.isCompleted + ftpReceiver.connMsg);

		if (ftpReceiver.isCompleted) {
			String tmpStrRetDes = FileHelper.readFileText(tmpLocalPath, getCharset());
			WriteBankLogLn2("回盘文件内容:\r\n" + tmpStrRetDes);
			String tmpStrRet = FileHelper.readFileText(tmpLocalPath, getCharset());
			// 解密文件
			if (getBankConfig().getValueAsBool("IsEncryption")) {
				String EncryptKey = getBankConfig().getValueAsString("EncryptKey");
				tmpLocalPath = FileEncryptionTest.decFile(tmpLocalPath, EncryptKey);
				tmpStrRet = FileHelper.readFileText(tmpLocalPath, getCharset());
				WriteBankLogLn2("回盘文件内容（解密后）:\r\n" + tmpStrRet);
			}
			if (StringHelper.hasAnyChar(tmpStrRet)) {
				retAts.respCode = "0";
				retAts.reqSeqID = p_req.reqSeqID;
				StringReader strReader = new StringReader(tmpStrRet);
				BufferedReader tmpReader = new BufferedReader(strReader);
				while (true) {
					String eachline = tmpReader.readLine();
					if (StringHelper.isNullOrEmpty(eachline)) {
						break;
					}
					if (eachline.indexOf("^") > 0) {
						// 工行地区号|工行网点号|保险公司代码|银行交易渠道|客户姓名|客户证件类型|客户证件号码|客户手机号码|客户银行卡号账号|保险公司协议种类|投保单号/保单号|出单渠道|单笔扣款限额|扣款频度|协议开始日期|协议到期日期|协议备注|处理结果|协议编号|协议状态\n
						String[] eachNodes = eachline.split("\\^");
						RetAtsQryAuthForRecDetail tmpRetDetail = new RetAtsQryAuthForRecDetail();
						tmpRetDetail.iSeqno = eachNodes[16].trim();
						tmpRetDetail.authCode = eachNodes[18].trim();
						tmpRetDetail.oppAct = eachNodes[8].trim();
						tmpRetDetail.oppActName = eachNodes[4].trim();
						tmpRetDetail.deadLine = Format.Date8Format.format(sdf.parse(eachNodes[15].trim()));
						String Result = eachNodes[17].trim();
						if ("0".equals(Result)) {
							tmpRetDetail.transState = "2";
						} else {
							tmpRetDetail.transState = "3";
						}
						tmpRetDetail.payCode = eachNodes[17].trim();
						if("1".equals(eachNodes[19].trim())){
							tmpRetDetail.payInfo = "生效";
						}
						if("2".equals(eachNodes[19].trim())){
							tmpRetDetail.payInfo = "待生效";
						}
						if("3".equals(eachNodes[19].trim())){
							tmpRetDetail.payInfo = "失效";
						}
						retAts.writeRetDetail(tmpRetDetail);

					}
				}
			} else {
				retAts.respCode = "-1";
				retAts.respInfo = "本地回盘结果文件内容为空!";
			}
		} else {
			retAts.respCode = "-1";
			retAts.respInfo = "回盘结果文件下载失败:" + ftpReceiver.connMsg;
		}
		retAts.writeAfterDetail();
		return retAts;
	}

	@Override
	public RetAtsQryRecAuthInfo d_qry_authInfo(ReqQryRecAuthInfo p_req) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

}
